#!/usr/bin/env python
# -*- coding:utf-8 -*-
'''
@File    :   Instance_class_properties.py
@Time    :   2025/01/14 20:17:41
@Author  :   xiangyu Chen
@Version :   1.0
@Contact :   yu112yu@sina.com
@License :   (C)Copyright 2017-2018, Liugroup-NLPR-CASIA
@python_requires    :   None
@Desc    :   实例属性和类属性
'''

'''
给实例绑定属性的方法是通过实例变量，或者通过 self 变量
'''


class Student(object):
    def __init__(self, name):
        self.name = name  # self 变量


s = Student('Bob')  # 创建实例
s.score = 90  # 实例变量
print('通过self 变量绑定的实例的属性，s.name :', s.name)
print('通过实例变量绑定的实例的属性，s.score ：', s.score)

# 类属性,直接在 class 中定义属性,归类所有.类的所有实例都可以访问到。


class Dog(object):
    count = 0

    def __init__(self, name):
        self.name = name
        Dog.count += 1  # 类属性
        print('Dog created in,self.__class__.__name__ :', self.__class__.__name__)
        # 类属性可以通过类名或者实例名来访问。
        print('Dog created in,Dog.count :', Dog.count)
        print(
            'Dog created in,Dog.__dict__[\'count\'] :', Dog.__dict__['count'])
        # 类属性也可以通过 del 删除。
        # del Dog.count


d1 = Dog('Tom')

d2 = Dog('Jerry')

print('Dog 类属性 count, d1.count,d2.count :', d1.count, d2.count)

# 由于实例属性优先级比类属性高，因此，它会屏蔽掉类的count 属性
d1.count = 3
print('after d1.count = 3, d1.count,d2.count :', d1.count, d2.count)

del Dog.count  # 删除类属性
try:
    # 由于实例属性优先级比类属性高，因此，它会屏蔽掉类的count 属性
    print('删除类属性，不影响实例属性，d1.count：', d1.count)
except AttributeError as e:
    print('Dog 类属性 count after del,d1.count :', e)
try:
    print('实例中无法访问del的类属性，d2.count：', d2.count)
except AttributeError as e:
    print('实例中无法访问del的类属性，d2.count： :', e)  # 类属性被删除后，在任何地方都无法访问。
# 类属性和实例属性的区别：
    # 类属性是类本身拥有的数据，不管有多少个实例，只有一份。
    # 实例属性是每个实例都拥有的数据，每个实例都有一份。
    # 类属性可以通过类名或者实例名来访问，而实例属性只能通过实例名来访问。
    # 类属性可以通过 del 删除。
